{{#operations}}
#import "{{classname}}.h"
#import "{{classPrefix}}QueryParamCollection.h"
#import "{{classPrefix}}ApiClient.h"
{{#imports}}#import "{{import}}.h"
{{/imports}}
{{newline}}

@interface {{classname}} ()

@property (nonatomic, strong, readwrite) NSMutableDictionary *mutableDefaultHeaders;

@end

@implementation {{classname}}

NSString* k{{classname}}ErrorDomain = @"{{classname}}ErrorDomain";
NSInteger k{{classname}}MissingParamErrorCode = 234513;

@synthesize apiClient = _apiClient;

#pragma mark - Initialize methods

- (instancetype) init {
    return [self initWithApiClient:[{{classPrefix}}ApiClient sharedClient]];
}


-(instancetype) initWithApiClient:({{classPrefix}}ApiClient *)apiClient {
    self = [super init];
    if (self) {
        _apiClient = apiClient;
        _mutableDefaultHeaders = [NSMutableDictionary dictionary];
    }
    return self;
}

#pragma mark -

-(NSString*) defaultHeaderForKey:(NSString*)key {
    return self.mutableDefaultHeaders[key];
}

-(void) setDefaultHeaderValue:(NSString*) value forKey:(NSString*)key {
    [self.mutableDefaultHeaders setValue:value forKey:key];
}

-(NSDictionary *)defaultHeaders {
    return self.mutableDefaultHeaders;
}

#pragma mark - Api Methods

{{#operation}}
///
/// {{{summary}}}
/// {{{notes}}}
/// {{#allParams}} @param {{paramName}} {{{description}}} {{^required}}(optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}
///
/// {{/allParams}} @returns {{{returnType}}}{{^returnType}}void{{/returnType}}
///
-(NSURLSessionTask*) {{#vendorExtensions.x-objc-operationId}}{{vendorExtensions.x-objc-operationId}}{{/vendorExtensions.x-objc-operationId}}{{^vendorExtensions.x-objc-operationId}}{{nickname}}{{#hasParams}}With{{vendorExtensions.x-first-param-alt-name}}{{/hasParams}}{{^hasParams}}WithCompletionHandler: {{/hasParams}}{{/vendorExtensions.x-objc-operationId}}{{#allParams}}{{^-first}}
    {{paramName}}{{/-first}}: ({{{dataType}}}) {{paramName}}{{/allParams}}
    {{#hasParams}}completionHandler: {{/hasParams}}(void (^)({{#returnBaseType}}{{{returnType}}} output, {{/returnBaseType}}NSError* error)) handler {
    {{#allParams}}
    {{#required}}
    // verify the required parameter '{{paramName}}' is set
    if ({{paramName}} == nil) {
        NSParameterAssert({{paramName}});
        if(handler) {
            NSDictionary * userInfo = @{NSLocalizedDescriptionKey : [NSString stringWithFormat:NSLocalizedString(@"Missing required parameter '%@'", nil),@"{{paramName}}"] };
            NSError* error = [NSError errorWithDomain:k{{classname}}ErrorDomain code:k{{classname}}MissingParamErrorCode userInfo:userInfo];
            handler({{#returnType}}nil, {{/returnType}}error);
        }
        return nil;
    }

    {{/required}}
    {{/allParams}}
    NSMutableString* resourcePath = [NSMutableString stringWithFormat:@"{{{path}}}"];

    NSMutableDictionary *pathParams = [[NSMutableDictionary alloc] init];
    {{#pathParams}}
    if ({{paramName}} != nil) {
        pathParams[@"{{baseName}}"] = {{paramName}};
    }
    {{/pathParams}}

    NSMutableDictionary* queryParams = [[NSMutableDictionary alloc] init];
    {{#queryParams}}
    if ({{paramName}} != nil) {
        {{#collectionFormat}}
        queryParams[@"{{baseName}}"] = [[{{classPrefix}}QueryParamCollection alloc] initWithValuesAndFormat: {{paramName}} format: @"{{collectionFormat}}"];
        {{/collectionFormat}}
        {{^collectionFormat}}
        {{#isBoolean}}
        queryParams[@"{{baseName}}"] = [{{paramName}} isEqual:@(YES)] ? @"true" : @"false";
        {{/isBoolean}}
        {{^isBoolean}}
        queryParams[@"{{baseName}}"] = {{paramName}};
        {{/isBoolean}}
        {{/collectionFormat}}
    }
    {{/queryParams}}
    NSMutableDictionary* headerParams = [NSMutableDictionary dictionaryWithDictionary:self.apiClient.configuration.defaultHeaders];
    [headerParams addEntriesFromDictionary:self.defaultHeaders];
    {{#headerParams}}
    if ({{paramName}} != nil) {
        headerParams[@"{{baseName}}"] = {{paramName}};
    }
    {{/headerParams}}
    // HTTP header `Accept`
    NSString *acceptHeader = [self.apiClient.sanitizer selectHeaderAccept:@[{{#produces}}@"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/produces}}]];
    if(acceptHeader.length > 0) {
        headerParams[@"Accept"] = acceptHeader;
    }

    // response content type
    NSString *responseContentType = [[acceptHeader componentsSeparatedByString:@", "] firstObject] ?: @"";

    // request content type
    NSString *requestContentType = [self.apiClient.sanitizer selectHeaderContentType:@[{{#consumes}}@"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/consumes}}]];

    // Authentication setting
    NSArray *authSettings = @[{{#authMethods}}@"{{name}}"{{^-last}}, {{/-last}}{{/authMethods}}];

    id bodyParam = nil;
    NSMutableDictionary *formParams = [[NSMutableDictionary alloc] init];
    NSMutableDictionary *localVarFiles = [[NSMutableDictionary alloc] init];
    {{#bodyParam}}
    bodyParam = {{paramName}};
    {{/bodyParam}}
    {{^bodyParam}}
    {{#formParams}}
    {{^isFile}}
    if ({{paramName}}) {
        formParams[@"{{baseName}}"] = {{paramName}};
    }
    {{/isFile}}
    {{#isFile}}
    localVarFiles[@"{{paramName}}"] = {{paramName}};
    {{/isFile}}
    {{/formParams}}
    {{/bodyParam}}

    return [self.apiClient requestWithPath: resourcePath
                                    method: @"{{httpMethod}}"
                                pathParams: pathParams
                               queryParams: queryParams
                                formParams: formParams
                                     files: localVarFiles
                                      body: bodyParam
                              headerParams: headerParams
                              authSettings: authSettings
                        requestContentType: requestContentType
                       responseContentType: responseContentType
                              responseType: {{^returnType}}nil{{/returnType}}{{#returnType}}@"{{{ returnType }}}"{{/returnType}}
                           completionBlock: ^(id data, NSError *error) {
                                if(handler) {
                                    handler({{#returnType}}({{{ returnType }}})data, {{/returnType}}error);
                                }
                            }];
}

{{/operation}}

{{newline}}
{{/operations}}
@end
